package com.sti.framework.core.web;

import com.alibaba.fastjson.JSONObject;
import com.sti.framework.core.security.jwt.JwtException;
import com.sti.framework.core.security.jwt.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Administrator
 */
@Component
@WebFilter(filterName = "requestWrapper", urlPatterns = {"/Api/**"})
public class RequestWrapperFilter implements Filter {
    @Value("${spring.refererUrl}")
    private String refererUrl;
    @Value("${spring.RefererVerification}")
    private boolean refererVerification;
    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet(Arrays.asList("/Api/User/Login", "/Api/User/Captcha")));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("init");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("destroy");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;
        String path;
        if (this.refererVerification) {
            path = req.getHeader("Referer");
            if (path == null || !path.contains(this.refererUrl)) {
                this.returnRes403(res, 403, 34039, "来源不合法！");
                return;
            }
        }

        res.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
        res.setHeader("Access-Control-Allow-Headers", "token, content-type, fakeid");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("x-frame-options", "SAMEORIGIN");
        if (req.getMethod().equals("OPTIONS")) {
            res.setStatus(HttpStatus.NO_CONTENT.value());
        } else {
            path = req.getRequestURI().substring(req.getContextPath().length()).replaceAll("[/]+$", "");
            boolean allowedPath = ALLOWED_PATHS.contains(path);
            if (allowedPath) {
                chain.doFilter(req, res);
            } else {
                String token = req.getHeader("token");
                if (StringUtils.isNotEmpty(token)) {
                    try {
                        Claims claims = JwtUtil.checkJWT(token);
                        Long role_id = (Long)claims.get("role_id", Long.class);
                        Long user_id = (Long)claims.get("user_id", Long.class);
                        String username = (String)claims.get("username", String.class);
                        request.setAttribute("user_id", user_id);
                        request.setAttribute("role_id", role_id);
                        request.setAttribute("username", username);
                    } catch (JwtException var13) {
//                        this.returnRes403(res, 403, var13.responseStatus.getCode(), var13.responseStatus.getMsg());
//                        return;
                    }
                }
//                HttpServletRequest req2 = new RequestWrapper((HttpServletRequest)request);
                chain.doFilter(request, res);
            }

        }
    }

    private void returnRes403(HttpServletResponse res, Integer httpStatus, Integer code, String msg) {
        JSONObject result = new JSONObject();
        result.put("msg", msg);
        result.put("code", code);
        result.put("data", (Object)null);
        PrintWriter out = null;

        try {
            res.setStatus(httpStatus);
            res.setContentType("application/json;charset=UTF-8");
            out = res.getWriter();
            out.write(result.toJSONString());
            out.flush();
        } catch (IOException var11) {
            var11.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }

        }

    }
}
